package com.zyl.queue;

import java.sql.Time;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;

/**
 * @author zhaoyl
 * @date 2024/5/16 21:42
 * @description 说明
 *　【1】SynchronousQueue是一个没有数据缓冲的BlockingQueue，生产者线程对其的插入操作put必须等待消费者的移除操作take。
 * 【2】SynchronousQueue 最大的不同之处在于，它的容量为 0，所以没有一个地方来暂存元素，
 * 导致每次取数据都要先阻塞，直到有数据被放入；同理，每次放数据的时候也会阻塞，直到有消费者来取。
 * 【3】需要注意的是，SynchronousQueue 的容量不是 1 而是 0，因为 SynchronousQueue 不需要去持有元素，
 * 它所做的就是直接传递（direct handoff）。由于每当需要传递的时候，SynchronousQueue 会把元素直接从生产者传给消费者，
 * 在此期间并不需要做存储，所以如果运用得当，它的效率是很高的。
 */
public class SynchronousQueueTest {
    public static void main(String[] args) {
        //同步队列
        BlockingQueue<String> blockingQueue = new SynchronousQueue<>();
        //线程1放入
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+"->"+"put A");
                blockingQueue.put("1-A");
                System.out.println(Thread.currentThread().getName()+"->"+"put B");
                blockingQueue.put("2-B");
                System.out.println(Thread.currentThread().getName()+"->"+"put C");
                blockingQueue.put("3-C");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"线程T1").start();

        //线程2获取
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+"->"+blockingQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+"->"+blockingQueue.take());
                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+"->"+blockingQueue.take());

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"线程T2").start();

    }
}

